package cn.dlc.com.symboltable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 邓立川
 * @date 2021/3/21 16:38
 * @desc 顺序表
 */

@Data
public class SymbolTable<Key, Value> {

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private class Node<Key, Value> {
        private Key key;
        private Value value;
        private Node<Key, Value> next;
    }

    private Node<Key, Value> head;
    private int num;

    public SymbolTable(){
        this.head = new Node<>(null,null,null);
        this.num = 0;
    }

    public int size(){
        return this.num;
    }

    // 获取对应key的元素
    public Value get(Key key) {

        Node<Key,Value> node = head;

        for (int i = 0; i < this.num; i++) {
            node = node.getNext();
            if(key.equals(node.getKey())) {
                // 找到这个key
                return node.getValue();
            }
        }
        return null;
    }

    // 添加
    public void put(Key key, Value value) {
        Node<Key,Value> node = head;

        while(node.getNext() != null) {
            node = node.getNext();
            // 获取下一个节点进行比较
            if(key.equals(node.getKey())) {
                // 如果要添加的key在系统里面已经存在了，替换值
                node.setValue(value);
                return;
            }
        }

        // 添加到链表头部
        // 获取原来的头部元素
        Node<Key, Value> oldFirstNode = head.getNext();
        // 添加新的元素在这个元素前面
        Node<Key, Value> newNode = new Node<>(key, value, oldFirstNode);
        // 指定新的元素为第一个元素
        head.setNext(newNode);

        // num++
        this.num++;
    }

    //
    public Value delete(Key key) {
        Node<Key,Value> node = head;

        while(node.getNext() != null) {
            node = node.getNext();
            // 获取下一个节点进行比较，如果是相同的
            if(key.equals(node.getKey())) {
                // 如果是相同的，那么就是要删掉这个
                // 我们直接指向这个几点的下一个节点
                node.setNext(node.getNext().getNext());
                this.num--;

                return node.getValue();
            }
        }

        return null;
    }
}
